package com.cskaoyan.controller.wx.service;

import com.cskaoyan.bean.bo.CouponExchangeBo;
import com.cskaoyan.bean.bo.CouponReceiveBo;
import com.cskaoyan.bean.entity.*;
import com.cskaoyan.common.util.StringUtils;
import com.cskaoyan.mapper.*;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 小程序
 * 优惠券
 * @Author Patrick 田赫
 * @Time 2021-10-23
 */
@Service
public class WxCouponServiceImpl implements WxCouponService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    CouponUserMapper couponUserMapper;

    @Autowired
    CartMapper cartMapper;

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    WxCouponUserMapper wxCouponUserMapper;

    @Autowired
    WxCouponMapper wxcouponMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @SneakyThrows
    @Override
    public int receive(CouponReceiveBo couponReceiveBo) {
        //获取用户信息，判断是否已登录
        String username = ((User) SecurityUtils.getSubject().getPrincipal()).getUsername();
        if (username == null) {
            return 1000;
        }
        //获取当前用户id
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(username).andDeletedEqualTo(false);
        List<User> users = userMapper.selectByExample(userExample);
        Integer userId = users.get(0).getId();
        //查找优惠券
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andIdEqualTo(couponReceiveBo.getCouponId()).andTypeEqualTo((short) 0).andDeletedEqualTo(false);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        //优惠券不存在或者已过期
        if (coupons == null || coupons.size() == 0) {
            return 742;
        }
        //取出特定优惠券
        Coupon coupon = coupons.get(0);
        //限量优惠券是否领完
        if (coupon.getTotal() == -1) {
            return 741;
        }
        //是否在领取时间
        //如果是绝对时间优惠券
        if (coupon.getTimeType() == 1) {
            //不在领取期限
            if (coupon.getEndTime().before(new Date()) || coupon.getStartTime().after(new Date())) {
                return 742;
            }
        }
        //相对时间优惠券
        if (coupon.getDays() < 1) {
            return 742;
        }
        //判断用户领取优惠券数量是否超过上限
        if (coupon.getLimit() != 0) {
            CouponUserExample couponUserExample = new CouponUserExample();
            couponUserExample.createCriteria().andUserIdEqualTo(userId).andCouponIdEqualTo(couponReceiveBo.getCouponId()).andDeletedEqualTo(false);
            List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);
            if (coupon.getLimit() < couponUsers.size()) {
                return 740;
            }
        }
        //更新优惠券数量
        if (coupon.getTotal() != 0) {
            Coupon updateCoupon = new Coupon();
            updateCoupon.setId(couponReceiveBo.getCouponId());
            if (coupon.getTotal() == 1) {
                //清空优惠券
                updateCoupon.setTotal(-1);
            } else {
                updateCoupon.setTotal(coupon.getTotal() - 1);
            }
            int i = couponMapper.updateByPrimaryKeySelective(updateCoupon);
        }
        //将coupon信息添加进couponUser
        CouponUser couponUser = new CouponUser();
        SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date addTime = time.parse(time.format(new Date()));
        if (coupon.getTimeType() == 0) {
            //相对时间优惠券
            Short days = coupon.getDays();
            couponUser.setStartTime(new Date());
            //得到n天后的时间（参考百度）
            Calendar now = Calendar.getInstance();
            now.setTime(couponUser.getStartTime());
            now.set(Calendar.DATE, now.get(Calendar.DATE) + days);
            couponUser.setEndTime(now.getTime());
        } else {
            //绝对时间优惠券
            couponUser.setStartTime(coupon.getStartTime());
            couponUser.setEndTime(coupon.getEndTime());
        }
        //封装并插入couponUser
        couponUser.setId(null);
        couponUser.setUserId(userId);
        couponUser.setCouponId(couponReceiveBo.getCouponId());
        couponUser.setStatus((short) 0);
        couponUser.setAddTime(addTime);
        couponUser.setUpdateTime(addTime);
        couponUser.setDeleted(false);
        int i = couponUserMapper.insertSelective(couponUser);
        return 0;
    }


    @SneakyThrows
    @Override
    public int exchange(CouponExchangeBo couponExchangeBo) {
        //获取用户信息，判断是否已登录
        //Object principal = (User) SecurityUtils.getSubject().getPrincipal();
        String username = ((User) SecurityUtils.getSubject().getPrincipal()).getUsername();
        if (username == null) {
            return 1000;
        }
        //获取当前用户id
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUsernameEqualTo(username).andDeletedEqualTo(false);
        List<User> users = userMapper.selectByExample(userExample);
        Integer userId = users.get(0).getId();
        //查找优惠券
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();
        if (!StringUtils.isEmpty(couponExchangeBo.getCode())) {
            criteria.andCodeEqualTo(couponExchangeBo.getCode());
        }
        criteria.andTypeEqualTo((short) 2).andStatusEqualTo((short) 0).andDeletedEqualTo(false);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        //优惠券不存在或者已过期
        if (coupons == null || coupons.size() == 0) {
            return 742;
        }
        //取出特定优惠券
        Coupon coupon = coupons.get(0);
        //限量优惠券是否领完
        if (coupon.getTotal() == -1) {
            return 741;
        }
        //是否在领取时间
        //如果是绝对时间优惠券
        if (coupon.getTimeType() == 1) {
            //不在领取期限
            if (coupon.getEndTime().before(new Date()) || coupon.getStartTime().after(new Date())) {
                return 742;
            }
        }
        //相对时间优惠券
        if (coupon.getDays() < 1) {
            return 742;
        }
        //判断用户领取优惠券数量是否超过上限
        if (coupon.getLimit() != 0) {
            CouponUserExample couponUserExample = new CouponUserExample();
            couponUserExample.createCriteria().andUserIdEqualTo(userId).andCouponIdEqualTo(coupon.getId()).andDeletedEqualTo(false);
            List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);
            for (CouponUser couponUser : couponUsers) {
                if (coupon.getLimit() < couponUsers.size()) {
                    return 740;
                }
            }
        }
        //更新优惠券数量
        if (coupon.getTotal() != 0) {
            Coupon updateCoupon = new Coupon();
            updateCoupon.setId(coupon.getId());
            if (coupon.getTotal() == 1) {
                //清空优惠券
                updateCoupon.setTotal(-1);
            } else {
                updateCoupon.setTotal(coupon.getTotal() - 1);
            }
            int i = couponMapper.updateByPrimaryKeySelective(updateCoupon);
        }
        //将coupon信息添加进couponUser
        CouponUser couponUser = new CouponUser();
        SimpleDateFormat time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date addTime = time.parse(time.format(new Date()));
        if (coupon.getTimeType() == 0) {
            //相对时间优惠券
            Short days = coupon.getDays();
            couponUser.setStartTime(new Date());
            //得到n天后的时间（参考百度）
            Calendar now = Calendar.getInstance();
            now.setTime(couponUser.getStartTime());
            now.set(Calendar.DATE, now.get(Calendar.DATE) + days);
            couponUser.setEndTime(now.getTime());
        } else {
            //绝对时间优惠券
            couponUser.setStartTime(coupon.getStartTime());
            couponUser.setEndTime(coupon.getEndTime());
        }
        //封装并插入couponUser
        couponUser.setId(null);
        couponUser.setUserId(userId);
        couponUser.setCouponId(coupon.getId());
        couponUser.setStatus((short) 0);
        couponUser.setAddTime(addTime);
        couponUser.setUpdateTime(addTime);
        couponUser.setDeleted(false);
        int i = couponUserMapper.insertSelective(couponUser);
        return 0;
    }

    @Override
    public List<WxCouponInfo> selectCouponList(Integer cartId, Integer grouponRulesId) {
        //取出用户的id
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        Integer UserId = user.getId();

        //拿用户所有的未过期、未使用的优惠券
        WxCouponUserExample couponUserExample = new WxCouponUserExample();
        WxCouponUserExample.Criteria couponUserExampleCriteria = couponUserExample.createCriteria();
        couponUserExampleCriteria.andDeletedEqualTo(false);
        couponUserExampleCriteria.andStartTimeLessThanOrEqualTo(new Date());
        couponUserExampleCriteria.andEndTimeGreaterThanOrEqualTo(new Date());
        couponUserExampleCriteria.andStatusEqualTo((short) 0);
        List<WxCouponUser> wxCouponUsers = wxCouponUserMapper.selectByExample(couponUserExample);

        //拿用户优惠券对应的优惠券规则
        LinkedList<Integer> couponId = new LinkedList<>();
        for (WxCouponUser wxCouponUser : wxCouponUsers) {
            couponId.add(wxCouponUser.getCouponId());
        }
        List<WxCoupon> wxCoupons = new LinkedList<>();
        if (couponId.size() != 0) {
            WxCouponExample wxCouponExample = new WxCouponExample();
            WxCouponExample.Criteria wxCouponExampleCriteria = wxCouponExample.createCriteria();
            wxCouponExampleCriteria.andIdIn(couponId);
            wxCoupons = wxcouponMapper.selectByExample(wxCouponExample);
        }

        //在购物车中下单和快速下单分开处理
        List<Cart> carts;
        if (cartId == 0) {
            //在购物车中下单
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            criteria.andUserIdEqualTo(UserId);
            criteria.andCheckedEqualTo(true);
            criteria.andDeletedEqualTo(false);
            carts = cartMapper.selectByExample(cartExample);
        } else {
            //快速下单
            CartExample cartExample = new CartExample();
            CartExample.Criteria criteria = cartExample.createCriteria();
            criteria.andIdEqualTo(cartId);
            carts = cartMapper.selectByExample(cartExample);
        }

        //订单总价
        BigDecimal OrderPrice = new BigDecimal(0);
        HashMap<Integer, BigDecimal> categoryAndPriceMap = new HashMap<>();
        HashMap<Integer, BigDecimal> goodsTypeAndPriceMap = new HashMap<>();
        for (Cart cart : carts) {
            Integer type = goodsMapper.selectByPrimaryKey(cart.getGoodsId()).getCategoryId();
            BigDecimal price = cart.getPrice().multiply(new BigDecimal(cart.getNumber()));
            OrderPrice = OrderPrice.add(price);
            while (!type.equals(0)) {

                if (categoryAndPriceMap.containsKey(type)) {
                    categoryAndPriceMap.put(type, categoryAndPriceMap.get(type).add(price));
                } else {
                    categoryAndPriceMap.put(type, price);
                }
                type = categoryMapper.selectByPrimaryKey(type).getPid();
            }
            Integer goodsId = cart.getGoodsId();
            if (goodsTypeAndPriceMap.containsKey(cart.getGoodsId())) {
                goodsTypeAndPriceMap.put(goodsId, goodsTypeAndPriceMap.get(goodsId).add(price));
            } else {
                goodsTypeAndPriceMap.put(goodsId, price);
            }
        }


        //查看商品、商品类型是否有对应优惠券
        LinkedList<WxCoupon> availableCouponList = new LinkedList<>();
        for (WxCoupon wxCoupon : wxCoupons) {
            Short type = wxCoupon.getGoodsType();
            String[] goodsValue = StringUtils.string2StringArrays(wxCoupon.getGoodsValue());
            switch (type) {
                case (short) 0:
                    if (wxCoupon.getMin().compareTo(OrderPrice) <= 0) {
                        availableCouponList.add(wxCoupon);
                    }
                    break;
                case (short) 1:
                    for (String s : goodsValue) {
                        Integer goodsType = Integer.valueOf(s);
                        if (categoryAndPriceMap.containsKey(goodsType) && categoryAndPriceMap.get(goodsType).compareTo(wxCoupon.getMin()) >= 0) {
                            availableCouponList.add(wxCoupon);
                        }
                    }
                    break;
                case (short) 2:
                    for (String s : goodsValue) {
                        Integer goodsId = Integer.valueOf(s);
                        if (goodsTypeAndPriceMap.containsKey(goodsId) && goodsTypeAndPriceMap.get(goodsId).compareTo(wxCoupon.getMin()) >= 0) {
                            availableCouponList.add(wxCoupon);
                        }
                    }
            }
        }

        //把查到的优惠券加到list中，（先按金额排序，后按过期时间排序）
        LinkedList<WxCouponInfo> wxCouponInfos = new LinkedList<>();
        for (WxCoupon wxCoupon : availableCouponList) {
            for (WxCouponUser wxCouponUser : wxCouponUsers) {
                if (wxCoupon.getId().equals(wxCouponUser.getCouponId())) {
                    WxCouponInfo wxCouponInfo = new WxCouponInfo();
                    wxCouponInfo.setMin(wxCoupon.getMin().doubleValue());
                    wxCouponInfo.setName(wxCoupon.getName());
                    //激活状态怎么判断
                    wxCouponInfo.setAvailable(true);
                    wxCouponInfo.setDiscount(wxCoupon.getDiscount().doubleValue());
                    wxCouponInfo.setId(wxCouponInfo.getId());
                    Date startTime = wxCouponUser.getStartTime();
                    Date endTime = wxCouponUser.getEndTime();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    wxCouponInfo.setStartTime(simpleDateFormat.format(startTime));
                    wxCouponInfo.setTag(wxCoupon.getTag());
                    wxCouponInfo.setEndTime(simpleDateFormat.format(endTime));
                    wxCouponInfo.setCid(wxCoupon.getId());
                    wxCouponInfo.setDesc(wxCoupon.getDesc());
                    wxCouponInfos.add(wxCouponInfo);
                }
            }
        }
        //排序
        wxCouponInfos.sort(((o1, o2) -> {
            int i;
            if ((i = (int) (o2.getDiscount() - o1.getDiscount())) == 0) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    return simpleDateFormat.parse(o1.getEndTime()).compareTo(simpleDateFormat.parse(o2.getEndTime()));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            return i;
        }));
        return wxCouponInfos;
    }
    }




